package com.thinkgem.jeesite.modules.sys.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.thinkgem.jeesite.common.persistence.BasePage;
import com.thinkgem.jeesite.common.utils.StringUtils;
import com.thinkgem.jeesite.modules.sys.SysConstants;
import com.thinkgem.jeesite.modules.sys.dao.SysUserMapper;
import com.thinkgem.jeesite.modules.sys.entity.SysUser;
import com.thinkgem.jeesite.modules.sys.entity.SysUserChangeLog;
import com.thinkgem.jeesite.modules.sys.utils.SysCacheUtils;
import com.thinkgem.jeesite.modules.sys.utils.UserUtils;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @Author:Kongxiangsheng
 * @DesCription:
 * @Date:Created in 7:01 2018/8/15
 * @Modified By:
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class SysUserService extends ServiceImpl<SysUserMapper, SysUser> implements IService<SysUser> {
    @Autowired
    private SysRoleService sysRoleService;
    @Autowired
    private SysUserChangeLogService sysUserChangeLogService;

    /**
     * 清理用户缓存
     *
     * @param sysUser
     */
    private void clearUserCache(SysUser sysUser) {
        SysCacheUtils.removeSysUserById(sysUser.getId());
        SysCacheUtils.removeSysUserByLoginName(sysUser.getLoginName());
    }

    /**
     * 删除用户角色信息
     *
     * @param userId
     * @return
     */
    private int deleteUserRoles(String userId) {
        return this.baseMapper.deleteUserRoles(userId);
    }

    /**
     * 插入用户角色信息
     *
     * @param user
     * @return
     */
    private int insertUserRoles(SysUser user) {
        if (CollectionUtils.isEmpty(user.getRoleList())) {
            return 0;
        }
        return this.baseMapper.insertUserRoles(user);
    }

    /**
     * 保存变更历史
     *
     * @param newUser
     * @return
     */
    private boolean saveChangeLog(SysUser oldUser, SysUser newUser) {
        if (null == oldUser) {
            return false;
        }
        boolean needSave = false;
        String oldCompanyId = null == oldUser.getCompanyId() ? "" : oldUser.getCompanyId();
        String newCompanyId = null == newUser.getCompanyId() ? "" : newUser.getCompanyId();
        if (!oldCompanyId.equals(newCompanyId)) {
            needSave = true;
        }
        String oldOfficeId = null == oldUser.getOfficeId() ? "" : oldUser.getOfficeId();
        String newOfficeId = null == newUser.getOfficeId() ? "" : newUser.getOfficeId();
        if (!oldOfficeId.equals(newOfficeId)) {
            needSave = true;
        }
        String oldLoginName = null == oldUser.getLoginName() ? "" : oldUser.getLoginName();
        String newLoginName = null == newUser.getLoginName() ? "" : newUser.getLoginName();
        if (!oldLoginName.equals(newLoginName)) {
            needSave = true;
        }
        String oldPassword = null == oldUser.getPassword() ? "" : oldUser.getPassword();
        String newPassword = null == newUser.getPassword() ? "" : newUser.getPassword();
        if (!oldPassword.equals(newPassword)) {
            needSave = true;
        }
        String oldNo = null == oldUser.getNo() ? "" : oldUser.getNo();
        String newNo = null == newUser.getNo() ? "" : newUser.getNo();
        if (!oldNo.equals(newNo)) {
            needSave = true;
        }
        String oldName = null == oldUser.getName() ? "" : oldUser.getName();
        String newName = null == newUser.getName() ? "" : newUser.getName();
        if (!oldName.equals(newName)) {
            needSave = true;
        }
        String oldEmail = null == oldUser.getEmail() ? "" : oldUser.getEmail();
        String newEmail = null == newUser.getEmail() ? "" : newUser.getEmail();
        if (!oldEmail.equals(newEmail)) {
            needSave = true;
        }
        String oldPhone = null == oldUser.getPhone() ? "" : oldUser.getPhone();
        String newPhone = null == newUser.getPhone() ? "" : newUser.getPhone();
        if (!oldPhone.equals(newPhone)) {
            needSave = true;
        }
        String oldMobile = null == oldUser.getMobile() ? "" : oldUser.getMobile();
        String newMobile = null == newUser.getMobile() ? "" : newUser.getMobile();
        if (!oldMobile.equals(newMobile)) {
            needSave = true;
        }
        String oldUserType = null == oldUser.getUserType() ? "" : oldUser.getUserType();
        String newUserType = null == newUser.getUserType() ? "" : newUser.getUserType();
        if (!oldUserType.equals(newUserType)) {
            needSave = true;
        }
        String oldPhoto = null == oldUser.getPhoto() ? "" : oldUser.getPhoto();
        String newPhoto = null == newUser.getPhoto() ? "" : newUser.getPhoto();
        if (!oldPhoto.equals(newPhoto)) {
            needSave = true;
        }
        String oldLoginIp = null == oldUser.getLoginIp() ? "" : oldUser.getLoginIp();
        String newLoginIp = null == newUser.getLoginIp() ? "" : newUser.getLoginIp();
        if (!oldLoginIp.equals(newLoginIp)) {
            needSave = true;
        }
        String oldLoginFlag = null == oldUser.getLoginFlag() ? "" : oldUser.getLoginFlag();
        String newLoginFlag = null == newUser.getLoginFlag() ? "" : newUser.getLoginFlag();
        if (!oldLoginFlag.equals(newLoginFlag)) {
            needSave = true;
        }

        if (needSave) {
            SysUserChangeLog log = new SysUserChangeLog(newUser);
            return sysUserChangeLogService.save(log);
        } else {
            return false;
        }
    }

    /**
     * 新增用户保存，同时保存角色信息
     *
     * @param sysUser
     * @return
     */
    private boolean insertUser(SysUser sysUser) {
        if (StringUtils.isBlank(sysUser.getUserType())) {
            sysUser.setUserType(SysConstants.UserType.MANAGER);
        }
        if (StringUtils.isBlank(sysUser.getCompanyId())) {
            SysUser currentUser = UserUtils.getUser();
            sysUser.setCompanyId(null == currentUser ? "1" : currentUser.getCompanyId());
        }
        this.save(sysUser);
        this.insertUserRoles(sysUser);

        // 保存变更历史
        saveChangeLog(null, sysUser);

        // 清理缓存
        clearUserCache(sysUser);
        return true;
    }

    /**
     * 用户信息修改，同时更新用户的角色信息
     *
     * @param sysUser
     * @return
     */
    // TODO: 思考一下这个方法会不会被mybatis的一级缓存影响到
    private boolean updateUser(SysUser sysUser) {
        // 清除原用户机构用户缓存
        SysUser oldUser = this.getById(sysUser.getId());

        // 保存变更历史
        saveChangeLog(oldUser, sysUser);

        // 更新用户信息
        this.updateById(sysUser);

        // 更新用户与角色关联
        if (CollectionUtils.isNotEmpty(sysUser.getRoleList())) {
            this.deleteUserRoles(sysUser.getId());
            this.insertUserRoles(sysUser);
        }

        // 清理缓存
        clearUserCache(oldUser);
        clearUserCache(sysUser);
        // TODO: 查找该用户的session，如果存在，则清空session数据并强制用户下线

        return true;
    }

    /**
     * 根据ID获取用户
     *
     * @param id
     * @return
     */
    public SysUser get(String id) {
        // 先从缓存获取
        SysUser sysUser = SysCacheUtils.getSysUserById(id);
        if (null != sysUser) {
            return sysUser;
        }

        // 缓存中不存在，则从数据库获取
        sysUser = this.baseMapper.selectById(id);
        if (null != sysUser) {
            sysUser.setRoleList(sysRoleService.findByUserId(sysUser.getId()));
            SysCacheUtils.putSysUserById(sysUser.getId(), sysUser);
            SysCacheUtils.putSysUserByLoginName(sysUser.getLoginName(), sysUser);
        }

        return sysUser;
    }

    /**
     * 根据登录名获取
     *
     * @param loginName
     * @return
     */
    public SysUser getByLoginName(String loginName) {
        SysUser sysUser = SysCacheUtils.getSysUserByLoginName(loginName);
        if (null == sysUser) {
            QueryWrapper<SysUser> wrapper = new QueryWrapper();
            wrapper.eq(SysUser.COL_LOGIN_NAME, loginName);
            sysUser = this.baseMapper.selectOne(wrapper);
        }
        if (null == sysUser) {
            return null;
        }
        sysUser.setRoleList(sysRoleService.findByUserId(sysUser.getId()));
        SysCacheUtils.putSysUserById(sysUser.getId(), sysUser);
        SysCacheUtils.putSysUserByLoginName(sysUser.getLoginName(), sysUser);
        return sysUser;
    }

    /**
     * 查找拥有某角色的用户
     *
     * @param roleId
     * @return
     */
    public List<SysUser> findUserByRoleId(String roleId) {
        return this.baseMapper.findUserByRoleId(roleId);
    }

    /**
     * 保存用户信息
     *
     * @param sysUser
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean saveUser(SysUser sysUser) {
        if (StringUtils.isBlank(sysUser.getId())) {
            this.insertUser(sysUser);
        } else {
            this.updateUser(sysUser);
        }
        return true;
    }

    /**
     * 删除用户信息，同时删除用户角色信息
     *
     * @param sysUser
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteUser(SysUser sysUser) {
        // 删除用户角色信息
        this.deleteUserRoles(sysUser.getId());
        // 删除用户信息
        this.baseMapper.deleteById(sysUser);
        // TODO: 查找该用户的session，如果存在，则清空session数据并强制用户下线

        // TODO: 删除该用户的缓存信息

        return true;
    }

    /**
     * 根据机构Id获取用户（只获取id和那么字段，用于树的展示）
     *
     * @param officeId
     * @return
     */
    public List<SysUser> findUserByOfficeId(String officeId) {
        QueryWrapper queryWrapper = new QueryWrapper<SysUser>();
        queryWrapper.select(SysUser.COL_ID, SysUser.COL_NAME);
        queryWrapper.eq(SysUser.COL_OFFICE_ID, officeId);
        List<SysUser> list = this.baseMapper.selectList(queryWrapper);
        return list;
    }

    /**
     * 分页查询用户信息
     *
     * @param page
     * @param sysUser
     * @return
     */
    public BasePage<SysUser> selectUserPage(BasePage<SysUser> page, SysUser sysUser) {
        if (StringUtils.isBlank(sysUser.getCompanyId())) {
            sysUser.setCompanyId(UserUtils.getUser().getCompanyId());
        }
        if (StringUtils.isBlank(sysUser.getOfficeId())) {
            sysUser.setOfficeId(UserUtils.getUser().getOfficeId());
        }
        page.setRecords(this.baseMapper.selectUserList(page, sysUser));
        return page;
    }

    /**
     * 查询微信会员信息
     *
     * @param page
     * @param sysUser
     * @return
     */
    public BasePage<SysUser> selectWechatPage(BasePage<SysUser> page, SysUser sysUser) {
        sysUser.setCompanyId(null);
        sysUser.setOfficeId(null);
        page.setRecords(this.baseMapper.selectUserList(page, sysUser));
        return page;
    }
}
